package com.starbaba.core.web.translate;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.starbaba.core.utils.ConvertUtils;
import com.starbaba.core.utils.ReflectionUtils;
import com.starbaba.core.web.translate.service.TranslateService;
import com.starbaba.system.syscode.model.SyscodeVO;
import com.starbaba.system.syscode.service.SyscodeService;
import com.tuanzi.server.loan_base.util.DateFormatFactory;

@Component
@SuppressWarnings("all")
public class TranslateUtils implements Serializable{
	
	static Logger logger = Logger.getLogger(TranslateUtils.class);

	public static final String SYSCODE_PREFIX = "$"; // 调用SYSCODE的翻译
	
	public static final String DATE_PREFIX = "#"; //日期类型

	public static final String REFLECT_PREFIX = "!"; // 以java类反射机制取翻译类
	
	public static final String REFLECT_ALL_PREFIX = "&"; // 以java类反射机制取翻译类，获取所有结果集，并组合成一个字符串

	public static final String SEPARATOR = "*";
	
	public static final String BRACES = "{";
	
	private TranslateService translateService;
	
	private SyscodeService syscodeService;

	public TranslateService getTranslateService() {
		return translateService;
	}

	@Autowired @Qualifier("translateServiceImpl")
	public void setTranslateService(TranslateService translateService) {
		this.translateService = translateService;
	}
	
	public SyscodeService getSyscodeService() {
		return syscodeService;
	}
	
	@Autowired @Qualifier("syscodeServiceImpl")
	public void setSyscodeService(SyscodeService syscodeService) {
		this.syscodeService = syscodeService;
	}
	
	public String getName(String definition, String value){
		return this.getName(definition, value, true);
	}
	
	public String getName_table(String definition, String value){
		return this.getName_table(definition, value, true);
	}

	
	/**
	 * 通过definition进行翻译取值
	 * @param @param definition
	 * @param @param value
	 * @param @param isReturnOrginValue 是否返回原始值,
	 * isReturnOrginValue = true 	代表当翻译无值时,返回原值
	 * isReturnOrginValue = false	代表当翻译无值时,返回""
	 * @return String
	 * @throws
	 */
	public String getName(String definition, String value, boolean isReturnOrginValue){
		if(StringUtils.isBlank(value) || "null".equalsIgnoreCase(StringUtils.trim(value)))return "";
		try {
			if(StringUtils.isBlank(definition)){
				if(isReturnOrginValue){
					return value.toString().trim();
				}else{
					return "";
				}
			}
			definition = definition.trim();
			if (definition.startsWith(SYSCODE_PREFIX)){
				/**
				 * $DISCMAN
				 * $DISCMAN*code*kindname
				 */
				String transDef = definition.substring(SYSCODE_PREFIX.length());
				String type = transDef;
				String propertyName = null;
				if (transDef.indexOf(SEPARATOR) > 0) {
					type = transDef.substring(0, transDef.indexOf(SEPARATOR));
					propertyName = transDef.substring(transDef.indexOf(SEPARATOR) + 1);
					String code = "";
					String name = "";
					if(propertyName.indexOf(SEPARATOR) > 0){
						code = propertyName.substring(0, propertyName.indexOf(SEPARATOR));
						name = propertyName.substring(propertyName.indexOf(SEPARATOR) + 1);
						return this.getSyscodeName(type, value, code, name, isReturnOrginValue);
					}else{
						throw new Exception("标签配置有误[" + definition + "]");
					}
				}else{
					return this.getSyscodeName(type, value, "code", "kindname", isReturnOrginValue);
				}
			}else if(definition.startsWith(REFLECT_PREFIX)){
				/**
				 * !com.maywide.system.user.model.UserVO*userId*userName
				 */
				String descInfo = definition.substring(REFLECT_PREFIX.length());
				
				if (descInfo.indexOf(SEPARATOR) > 0) {
					String className = descInfo.substring(0, descInfo.indexOf(SEPARATOR));
					String propertyCluster = descInfo.substring(descInfo.indexOf(SEPARATOR) + 1);
					if(propertyCluster.indexOf(SEPARATOR) > 0){
						String propertyCode = propertyCluster.substring(0, propertyCluster.indexOf(SEPARATOR));
						String propertyName = propertyCluster.substring(propertyCluster.indexOf(SEPARATOR) + 1);
						return this.getReflectName(className, value, propertyCode, propertyName, isReturnOrginValue);
					}else{
						throw new Exception("标签配置有误[" + definition + "]");
					}
				}
			} else if(definition.startsWith(REFLECT_ALL_PREFIX)){
				/**
				 * &com.maywide.system.user.model.UserVO*userId*userName|，
				 */
				final String DESC_SPERTOR = "|";
				String descInfo = StringUtils.substringAfter(definition, REFLECT_ALL_PREFIX);
				String descSper = " ";
				if(StringUtils.contains(descInfo, DESC_SPERTOR)) {
					descSper = StringUtils.defaultIfEmpty(StringUtils.substringAfter(descInfo, DESC_SPERTOR), " ");
					descInfo = StringUtils.substringBefore(descInfo, DESC_SPERTOR);
				}
				if (StringUtils.contains(descInfo, SEPARATOR)) {
					String className = descInfo.substring(0, descInfo.indexOf(SEPARATOR));
					String propertyCluster = descInfo.substring(descInfo.indexOf(SEPARATOR) + 1);
					if(propertyCluster.indexOf(SEPARATOR) > 0){
						String propertyCode = propertyCluster.substring(0, propertyCluster.indexOf(SEPARATOR));
						String propertyName = propertyCluster.substring(propertyCluster.indexOf(SEPARATOR) + 1);
						return this.getAllReflectName(className, value, propertyCode, propertyName, descSper, isReturnOrginValue);
					}else{
						throw new Exception("标签配置有误[" + definition + "]");
					}
				}
			} else if(definition.startsWith(DATE_PREFIX)){
				try{
					String format = definition.substring(DATE_PREFIX.length());
					return DateFormatFactory.getInstance(format).format(ConvertUtils.convertStringToObject(value, java.util.Date.class));
				}catch(Exception ex){
					return value.toString();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(isReturnOrginValue){
			return value.toString();
		}else{
			return "";
		}
		
	}
	
	
	
	/**
	 * 通过definition进行翻译取值(翻译餐厅桌号)
	 * @param @param definition
	 * @param @param value
	 * @param @param isReturnOrginValue 是否返回原始值,
	 * isReturnOrginValue = true 	代表当翻译无值时,返回原值
	 * isReturnOrginValue = false	代表当翻译无值时,返回""
	 * @return String
	 * @throws
	 */
	public String getName_table(String definition, String value, boolean isReturnOrginValue){
		if(StringUtils.isBlank(value))return "";
		try {
			if(StringUtils.isBlank(definition)){
				if(isReturnOrginValue){
					return value.toString().trim();
				}else{
					return "";
				}
			}
			definition = definition.trim();
			if (definition.startsWith(SYSCODE_PREFIX)){
				/**
				 * $DISCMAN
				 * $DISCMAN*kind*kindname
				 */
				String transDef = definition.substring(SYSCODE_PREFIX.length());
				String type = transDef;
				String propertyName = null;
				if (transDef.indexOf(SEPARATOR) > 0) {
					type = transDef.substring(0, transDef.indexOf(SEPARATOR));
					propertyName = transDef.substring(transDef.indexOf(SEPARATOR) + 1);
					String code = "";
					String name = "";
					if(propertyName.indexOf(SEPARATOR) > 0){
						code = propertyName.substring(0, propertyName.indexOf(SEPARATOR));
						name = propertyName.substring(propertyName.indexOf(SEPARATOR) + 1);
						return this.getSyscodeName(type, value, code, name, isReturnOrginValue);
					}else{
						throw new Exception("标签配置有误[" + definition + "]");
					}
				}else{
					return this.getSyscodeName(type, value, "code", "kindname", isReturnOrginValue);
				}
			}else if(definition.startsWith(REFLECT_PREFIX)){
				/**
				 * !com.maywide.system.user.model.UserVO*userId*userName
				 */
				String descInfo = definition.substring(REFLECT_PREFIX.length());
				
				if (descInfo.indexOf(SEPARATOR) > 0) {
					String className = descInfo.substring(0, descInfo.indexOf(SEPARATOR));
					String propertyCluster = descInfo.substring(descInfo.indexOf(SEPARATOR) + 1);
					if(propertyCluster.indexOf(SEPARATOR) > 0){
						String propertyCode = propertyCluster.substring(0, propertyCluster.indexOf(SEPARATOR));
						String propertyName = propertyCluster.substring(propertyCluster.indexOf(SEPARATOR) + 1);
						String[] values = value.split("&");
						StringBuffer name = new StringBuffer();
						for(int i=0;i<values.length;i++){
							String temp = TranslateUtilsFactory.getInstance().getName(definition, values[i]);
							name.append(temp);
							if(i!=values.length)
							name.append(" ");
						}
						return name.toString();
						
						//return this.getReflectName(className, value, propertyCode, propertyName, isReturnOrginValue);
					}else{
						throw new Exception("标签配置有误[" + definition + "]");
					}
				}
			} else if(definition.startsWith(REFLECT_ALL_PREFIX)){
				/**
				 * &com.maywide.system.user.model.UserVO*userId*userName|，
				 */
				final String DESC_SPERTOR = "|";
				String descInfo = StringUtils.substringAfter(definition, REFLECT_ALL_PREFIX);
				String descSper = " ";
				if(StringUtils.contains(descInfo, DESC_SPERTOR)) {
					descSper = StringUtils.defaultIfEmpty(StringUtils.substringAfter(descInfo, DESC_SPERTOR), " ");
					descInfo = StringUtils.substringBefore(descInfo, DESC_SPERTOR);
				}
				if (StringUtils.contains(descInfo, SEPARATOR)) {
					String className = descInfo.substring(0, descInfo.indexOf(SEPARATOR));
					String propertyCluster = descInfo.substring(descInfo.indexOf(SEPARATOR) + 1);
					if(propertyCluster.indexOf(SEPARATOR) > 0){
						String propertyCode = propertyCluster.substring(0, propertyCluster.indexOf(SEPARATOR));
						String propertyName = propertyCluster.substring(propertyCluster.indexOf(SEPARATOR) + 1);
						return this.getAllReflectName(className, value, propertyCode, propertyName, descSper, isReturnOrginValue);
					}else{
						throw new Exception("标签配置有误[" + definition + "]");
					}
				}
			} else if(definition.startsWith(DATE_PREFIX)){
				try{
					String format = definition.substring(DATE_PREFIX.length());
					return DateFormatFactory.getInstance(format).format(ConvertUtils.convertStringToObject(value, java.util.Date.class));
				}catch(Exception ex){
					return value.toString();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(isReturnOrginValue){
			return value.toString();
		}else{
			return "";
		}
		
	}		
	
	/**
	 * 获取页面列表信息
	 * @param @param definition
	 * @param @param listKey
	 * @param @param listValue
	 * @param @param needSpace
	 * @return List<TranslateVO>
	 * @throws
	 */
	@SuppressWarnings("unchecked")
	public List<TranslateVO> getCollection(String definition) {
		if (StringUtils.isBlank(definition)){
			return new ArrayList();
		}
		try {
			if (definition.startsWith(SYSCODE_PREFIX)){
				/**
				 * 调用SYSCODE的列表生成方式有如下两种形式
				 * $DISCMAN
				 * $DISCMAN*data1*dataname1
				 */
				String transDef = definition.substring(SYSCODE_PREFIX.length());
				String type = transDef;				
				if (transDef.indexOf(SEPARATOR) > 0) {
					type = transDef.substring(0, transDef.indexOf(SEPARATOR));
					String propertyName = transDef.substring(transDef.indexOf(SEPARATOR) + 1);
					String listKey = "";
					String listValue = "";
					if(propertyName.indexOf(SEPARATOR) > 0){
						listKey = propertyName.substring(0, propertyName.indexOf(SEPARATOR));
						listValue = propertyName.substring(propertyName.indexOf(SEPARATOR) + 1);
						return this.getSyscodeTranslateCollection(type, listKey, listValue);
					}
				}else{
					return this.getSyscodeTranslateCollection(type, "code", "kindname");
				}
			}else if(definition.startsWith(REFLECT_PREFIX)){
				/**
				 * 反射机制进行列表生成,反射机制要求写全标签信息
				 * !com.starbaba.xx.xxVO*code*name
				 */
				String descInfo = definition.substring(SYSCODE_PREFIX.length());
				String []array = StringUtils.split(descInfo, SEPARATOR);
				if(array.length >= 3){
					String className = array[0];
					String code = array[1];
					String name = array[2];
					return this.getRelectTranslateCollection(className, code, name);
				}
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}
		return new ArrayList();
	}
	
	
	
	public List<TranslateVO> getSyscodeTranslateCollection(String type, String listKey, String listValue) throws Exception{
		List<SyscodeVO> list = this.getSyscodeVOCollectionByType(type);
		return this.getTranslateVOList(list, listKey, listValue);
	}
	
	public List<SyscodeVO> getSyscodeVOCollectionByType(String type) throws Exception{
		if(type.equals("carparktype")){
			return this.getSyscodeService().doFindSyscodeVOByType(type,new int[]{-1,104});
		}
		return this.getSyscodeService().doFindSyscodeVOByType(type);
	}
	
	public List<TranslateVO> getRelectTranslateCollection(String className, String listKey, String listValue) throws Exception{
		List<?> list = this.getReflectVOCollection(className);
		return this.getTranslateVOList(list, listKey, listValue);
	}
	
	@SuppressWarnings("unchecked")
	public List getReflectVOCollection(String className) throws Exception{
		Class entityClass = Class.forName(className);
		return this.getTranslateService().doFindALL(entityClass);
	}
	
	@SuppressWarnings("unchecked")
	public List<TranslateVO> getTranslateVOList(List targetList, String listKey, String listValue) throws Exception{
		List<TranslateVO> list = new ArrayList<TranslateVO>();
		if(null != targetList && targetList.size() > 0){
			for (Iterator iter = targetList.iterator(); iter.hasNext();) {
				Object targetVO = iter.next();
				TranslateVO translateVO = new TranslateVO();
				translateVO.setCode(BeanUtils.getProperty(targetVO, listKey));
				translateVO.setName(BeanUtils.getProperty(targetVO, listValue));
				list.add(translateVO);
			}
		}
		return list;
	}
	
	public String getSyscodeName(String type, String value, String propertyCode, String propertyName, boolean isReturnOrginValue) throws Exception{
		SyscodeVO syscodeVO = new SyscodeVO();
		syscodeVO.setType(type);
		BeanUtils.setProperty(syscodeVO, propertyCode, value);
		
		List list = this.getSyscodeService().doFindByExampleVO(SyscodeVO.class, syscodeVO);
		if(null != list && list.size() > 0){
			syscodeVO = (SyscodeVO) list.get(0);
			if(StringUtils.isNotBlank(propertyName)){
				return BeanUtils.getProperty(syscodeVO, propertyName.trim());
			}else{
				return syscodeVO.getKindname();
			}
		}
		if(isReturnOrginValue){
			return value.toString();
		}else{
			return "";
		}
	}
	
	
	@SuppressWarnings("unchecked")
	public String getReflectName(String className, String value, String propertyCode, String propertyName, boolean isReturnOrginValue) throws Exception{
		if (value == null ) return "";
		Class reflectClass = Class.forName(className);
		Class<?> fieldType = ReflectionUtils.getDeclaredFieldType(reflectClass, propertyCode);
		
		List list = this.getTranslateService().doFindByProperty(reflectClass, propertyCode, ConvertUtils.convertStringToObject(value, fieldType));
		
		if(null != list && list.size() > 0){
			Object example = list.get(0);
			if(StringUtils.isNotBlank(propertyName)){
				return BeanUtils.getProperty(example, propertyName.trim());
			}
		}
		if(isReturnOrginValue){
			return value.toString();
		}else{
			return "";
		}
	}
	
	@SuppressWarnings("unchecked")
	public String getAllReflectName(String className, String value, String propertyCode, String propertyName, String valuesSper, boolean isReturnOrginValue) throws Exception{
		if (value == null ) return "";
		Class reflectClass = Class.forName(className);
		Class<?> fieldType = ReflectionUtils.getDeclaredFieldType(reflectClass, propertyCode);
		List list = this.getTranslateService().doFindByProperty(reflectClass, propertyCode, ConvertUtils.convertStringToObject(value, fieldType));
		
		if(null != list && list.size() > 0){
			List valueList = new ArrayList();
			for(Iterator iter = list.iterator(); iter.hasNext(); ) {
				Object example = iter.next();
				if(StringUtils.isNotBlank(propertyName)){
					valueList.add(BeanUtils.getProperty(example, propertyName.trim()));
				}
			}
			value = StringUtils.join(valueList.iterator(), valuesSper);
		}
		if(isReturnOrginValue){
			return value.toString();
		}else{
			return "";
		}
	}

	
	/**
	 * 翻译类型(提供批量导入模块使用)
	 * 在后台批量导入模块中，如果以字典表进行翻译, 使用的是逆向翻译
	 * @param value
	 * @param definition
	 * @return
	 * @throws Exception 
	 */
	public String format(String definition, String value) throws Exception{
		return this.format(definition, value, false);
	}
	
	public String format(String definition, String value, boolean isReturnOrginValue) throws Exception{
		if(definition.startsWith(SYSCODE_PREFIX) && definition.indexOf(SEPARATOR) < 0){
			definition = definition + "*kindname*kind";
		}
		return this.getName(definition, value, isReturnOrginValue);
	}
	
}
